var PLUGIN = null;

// #ifdef MP
// var Plugin = requirePlugin("myPlugin");
var createPlugin = requirePlugin('myPlugin')
var Plugin = createPlugin()
// #endif


var currentPluginInstance = null;
var pingTimer = null;
var TIMEOUT = 25000; // ping心跳的间隔，该值小于设备自动断连的超时(30000ms)即可

class PluginManager {
  keyGroupId = 900; // 由业务服务器返回

  lockMac = ""; // 通过API: getBroadcastData 获得

  aesKey = ""; // 通过API: addBluetoothDevice 获得

  authCode = ""; // 通过API: addBluetoothDevice 获得

  connectBeforeGetBroadcastData = true;
  oad_debug = false; // 查看OAD升级日志，仅debug时使用

  successFunc = null; //蓝牙连接后的回调，一般用于开启同步钥匙列表的多次监听

  readyFunc = null; //ready监听的回调

  closeFunc = null; // 关闭连接监听的回调

  errorFunc = null; // 错误监听的回调

  reportOpenlock = null; //开锁上报的回调

  reportGeneral = null; //通用事件上报的回调

  reportRemoveKey = null; //删除钥匙事件上报

  eronBLECVC = null; //删除钥匙失败监听

  addKeyFunc = null; //添加钥匙监听

  reportAddKey = null; //添加钥匙上报

  /**
   * 初始构造方法
   */

  constructor(data) {
    if (!data) {
      this.lockMac = uni.getStorageSync('PLUGIN_LOCKMAC');
      this.aesKey = uni.getStorageSync('PLUGIN_AESKEY');
      this.authCode = uni.getStorageSync('PLUGIN_AUTHCODE');
    } else {
      this.lockMac = data.lockMac;
      this.aesKey = data.aesKey;
      this.authCode = data.authCode;
      data.keyGroupId ? this.keyGroupId = data.keyGroupId : "";
      data.connectBeforeGetBroadcastData ? this.connectBeforeGetBroadcastData = data.connectBeforeGetBroadcastData : "";
      data.oad_debug ? this.oad_debug = data.oad_debug : "";
      this.setWiretapping(data);
    }

    this.init();
  }
  /**
   * 配置传入的监听
   * @param {*} data 
   * successFunc 蓝牙连接后的回调，一般用于开启同步钥匙列表的多次监听
   * readyFunc ready监听的回调
   * closeFunc 关闭连接监听的回调
   * errorFunc 错误监听的回调
   * reportOpenlock 开锁上报的回调
   * reportGeneral 通用事件上报的回调
   * reportRemoveKey 删除钥匙事件上报
   * eronBLECVC 删除钥匙失败监听
   * addKeyFunc 添加钥匙监听
   * reportAddKey 添加钥匙上报
   */


  setWiretapping = data => {
    this.successFunc = data.success ? data.success : null;
    this.readyFunc = data.ready ? data.ready : null;
    this.closeFunc = data.close ? data.close : null;
    this.errorFunc = data.error ? data.error : null;
    this.reportOpenlock = data.reportOpenlock ? data.reportOpenlock : null;
    this.reportGeneral = data.reportGeneral ? data.reportGeneral : null;
    this.reportRemoveKey = data.reportRemoveKey ? data.reportRemoveKey : null;
    this.eronBLECVC = data.eronBLECVC ? data.eronBLECVC : null;
    this.addKeyFunc = data.addKey ? data.addKey : null;
    this.reportAddKey = data.reportAddKey ? data.reportAddKey : null;
  };
  /**
   * 存储锁具信息
   */

  saveConfig = () => {
    return new Promise((resolve, reject) => {
      uni.setStorageSync('PLUGIN_LOCKMAC', this.lockMac);
      uni.setStorageSync('PLUGIN_AESKEY', this.aesKey);
      uni.setStorageSync('PLUGIN_AUTHCODE', this.authCode);
      resolve("锁具信息已保存");
    });
  };
  /**
   * 清除锁具信息
   */

  clearConfig = () => {
    return new Promise((resolve, reject) => {
      uni.removeStorageSync('PLUGIN_LOCKMAC');
      uni.removeStorageSync('PLUGIN_AESKEY');
      uni.removeStorageSync('PLUGIN_AUTHCODE');
      resolve("锁具信息已清除");
    });
  };
  setConfig = data => {
    // this.config = {
    //   ...this.config,
    //   ...data
    // }
    this.lockMac = data.lockMac;
    this.aesKey = data.aesKey;
    this.authCode = data.authCode;
    this.saveConfig();
  };
  clearTimeout = () => {
    clearTimeout(pingTimer);
    pingTimer = null;
  };
  init = () => {
    uni.showLoading({
      title: "正在搜索设备",
      mask: true
    });
    var that = this;
    var config = {
      keyGroupId: this.keyGroupId
    };
    this.lockMac != "" ? config.lockMac = this.lockMac : "";
    this.aesKey != "" ? config.aesKey = this.aesKey : "";
    this.authCode != "" ? config.authCode = this.authCode : "";
    PLUGIN = new Plugin(config);
    console.log(JSON.stringify(config));
    PLUGIN.on("ready", function (data) {
      uni.hideLoading();
      console.info("plugin is on ready, state -->", data);
      uni.showToast({
        title: '设备已连接'
      });
      that.currentPluginInstance = data; //缓存实例

      that.ping(); //未添加蓝牙时，自动搜索符合的蓝牙并连接

      if (!that.lockMac || that.lockMac == "") {
        that.addBLD().then(res => {
          typeof that.readyFunc == "function" ? that.readyFunc(res) : "";
        });
      } else if (typeof that.readyFunc == "function") {
        that.readyFunc();
      } else if (typeof that.successFunc == "function") {
        that.successFunc();
      }
    }); // 监听“断开连接”事件

    PLUGIN.on("close", function (state) {
      uni.hideLoading();
      typeof that.closeFunc == "function" ? that.closeFunc(state) : "";
      console.info("plugin is on close, state -->", state);
    }); // 监听“运行错误”事件

    PLUGIN.on("error", function (err) {
      uni.hideLoading();
      uni.hideToast();

      if (err.errCode == 10001 || err.errCode == 10000) {
        uni.showToast({
          title: err.errMsg,
          icon: "none",
          duration: 3000
        });
      } else if (err.code == 100020) {
        uni.showToast({
          title: "未搜索到相关设备",
          icon: "none",
          duration: 3000
        });
      } else if (err.errMsg) {
        uni.showToast({
          title: err.errMsg,
          icon: "none",
          duration: 3000
        });
      }

      typeof that.errorFunc == "function" ? that.errorFunc(err) : "";
      console.info("plugin is on error -->", err);
    }); // 监听删除钥匙失败

    PLUGIN.on("eronBLECharacteristicValueChangeor", function (res) {
      console.info("plugin is on onBLECharacteristicValueChange -->", res);
      uni.hideLoading();
      typeof that.eronBLECVC == "function" ? that.eronBLECVC(res) : "";
    }); // 监听“开锁”事件上报

    PLUGIN.on("report:openLock", function (data) {
      uni.hideLoading();
      typeof that.reportOpenlock == "function" ? that.reportOpenlock(data) : "";
      console.info("plugin is on opened lock, data is ", data);
    }); // 监听“钥匙的使能与禁止”事件上报

    PLUGIN.on("report:enableKey", function (data) {
      uni.hideLoading();
      console.info("plugin is on enabled key, data is ", data);
    }); // 监听“添加钥匙”事件

    PLUGIN.on("addKey", function (data) {
      uni.hideLoading();
      typeof that.addKeyFunc == "function" ? that.addKeyFunc(data) : "";
      console.log('plugin is on addKey, data is ', data);
    }); // 监听“删除钥匙”事件上报

    PLUGIN.on("report:removeKey", function (data) {
      uni.hideLoading();
      typeof that.reportRemoveKey == "function" ? that.reportRemoveKey(data) : "";
      console.info("plugin is on remove key, data is ", data);
    }); // 监听“添加钥匙”事件上报

    PLUGIN.on("report:addKey", function (data) {
      uni.hideLoading();
      typeof that.reportAddKey == "function" ? that.reportAddKey(data) : "";
      console.info("plugin is on add key, data is ", data);
    }); // 监听“设置系统参数”事件上报

    PLUGIN.on("report:setSystemInfo", function (data) {
      uni.hideLoading();
      console.info("plugin is on set system info, data is ", data);
    }); // 监听“修改密码”事件上报

    PLUGIN.on("report:updatePassword", function (data) {
      uni.hideLoading();
      console.info("plugin is on updating password, data is ", data);
    }); // 监听通用事件上报

    PLUGIN.on("report:general", function (data) {
      uni.hideLoading();
      typeof that.reportGeneral == "function" ? that.reportGeneral(data) : "";
      console.info("plugin is on general event, data is ", data);
    });
  };
  /**
   * 开启同步钥匙列表的多次监听
   * @param {*} data 
   */

  synchronizeKeyListMul = callBack => {
    //监听同步钥匙列表
    PLUGIN.on("synchronizeKeyList", function (data) {
      console.log('timestamp -->', Date.now(), ' synchronizeKeyList data -->', data);
      callBack(data);
    });
  };
  /**
   * 校验门锁初始信息
   */

  lockInit = data => {
    data = data || {};
    var _data = {
      isSuccess: data.isSuccess || true,
      lockCreateTime: data.lockCreateTime || undefined
    };
    return new Promise((resolve, reject) => {
      PLUGIN.validateLockInitialInfo(_data).then(res => {
        resolve(res);
      }).catch(err => {
        reject(err);
      });
    });
  };
  /**
   * 开锁
   */

  openLock() {
    uni.showLoading({
      title: '开锁中'
    });
    return new Promise((resolve, reject) => {
      PLUGIN.openLock().then(res => {
        uni.hideLoading();
        uni.showToast({
          title: '已开锁'
        });
        resolve(res);
      }).catch(err => {
        uni.hideLoading();

        if (err.errCode == 'E2') {
          uni.showToast({
            title: err.errMsg,
            icon: 'none'
          });
        }

        reject(err);
      });
    });
  }
  /**
   * 添加蓝牙信息
   */


  addBLD() {
    var that = this;
    return new Promise((resolve, reject) => {
      PLUGIN.addBluetoothDevice().then(res => {
        that.lockMac = res.data.DNAInfo.lockMac;
        that.aesKey = res.data.DNAInfo.aesKey;
        that.authCode = res.data.DNAInfo.adminAuthCode;

        if (typeof that.successFunc == "function") {
          that.successFunc(res);
        }

        that.saveConfig();
        that.lockInit();
        resolve(res);
      }).catch(err => {
        reject(err);
      });
    });
  }
  /**
   * 获取广播数据
   */


  getBD = () => {
    return new Promise((resolve, reject) => {
      PLUGIN.getBroadcastData().then(res => {
        console.log("getBroadcastData res -->", res);
        resolve(res);
      }).catch(err => {
        reject(err);
      });
    });
  };
  /**
   * 删除蓝牙
   */

  removeBLD = () => {
    uni.showLoading({
      title: '正在断开连接'
    });
    var that = this;
    return new Promise((resolve, reject) => {
      PLUGIN.removeBluetoothDevice().then(res => {
        uni.hideLoading();
        uni.showToast({
          title: '连接已断开'
        });
        that.clearConfig();
        that.setConfig({
          lockMac: "",
          aesKey: "",
          authCode: ""
        });
        resolve(res);
      }).catch(err => {
        uni.hideLoading();
        reject(err);
      });
    });
  };
  /**
   * 断开连接
   */

  disconnect = () => {
    var that = this;
    uni.showLoading({
      title: '正在断开连接'
    });
    return new Promise((resolve, reject) => {
      PLUGIN.disconnect().then(res => {
        uni.showToast({
          title: '连接已断开'
        });
        resolve(true);
      });
    });
  };
  /**
   * 同步钥匙列表
   */

  synchronizeKeyList = () => {
    uni.showLoading({
      title: '正在同步'
    });
    return new Promise((resolve, reject) => {
      PLUGIN.synchronizeKeyList().then(function (res) {
        console.log("同步钥匙列表 synchronizeKeyList res -->", res);
        resolve(res);
      }).catch(function (err) {
        console.log("synchronizeKeyList err -->", err);
        reject(err);
      });
    });
  };
  /**
   * 读取系统状态和参数
   */

  readSystemInfo = () => {
    return new Promise((resolve, reject) => {
      PLUGIN.readSystemInfo().then(function (res) {
        console.log("读取系统状态和参数 readSystemInfo res -->", res);
        resolve(res);
      }).catch(function (err) {
        console.log("readSystemInfo err -->", err);
        reject(err);
      });
    });
  };
  /**
   * 同步门锁日志信息
   */

  synchronizeLockRecord = () => {
    uni.showLoading({
      title: '同步中'
    });
    return new Promise((resolve, reject) => {
      PLUGIN.synchronizeLockRecord().then(function (res) {
        uni.showToast({
          title: '信息已同步'
        });
        console.log("同步门锁日志信息 synchronizeLockRecord res -->", res);
        resolve(res);
      }).catch(function (err) {
        uni.showToast({
          title: '操作失败',
          icon: "none"
        });
        console.log("synchronizeLockRecord err -->", err);
        reject(err);
      });
    });
  };
  /**
   * 读取DNA
   */

  readDNAInfo = () => {
    return new Promise((resolve, reject) => {
      PLUGIN.readDNAInfo().then(function (res) {
        console.log("读取DNA readDNAInfo res -->", res);
        resolve(res);
      }).catch(function (err) {
        console.log("readDNAInfo err -->", err);
        reject(err);
      });
    });
  };
  /**
   * 同步门锁时间
   */

  synchronizeLockSystemTime = () => {
    uni.showLoading({
      title: '同步中'
    });
    return new Promise((resolve, reject) => {
      PLUGIN.synchronizeLockSystemTime().then(function (res) {
        uni.showToast({
          title: '时间已同步'
        });
        console.log("同步门锁时间 synchronizeLockSystemTime res -->", res);
        resolve(res);
      }).catch(function (err) {
        uni.showToast({
          title: '操作失败',
          icon: "none"
        });
        console.log("synchronizeLockSystemTime err -->", err);
        reject(err);
      });
    });
  };
  /**
   * 添加钥匙
   * @param {*} data 
   */

  addKey = data => {
    return new Promise((resolve, reject) => {
      PLUGIN.addKey(data).then(function (res) {
        console.log("addKey2 res -->", res);
        resolve(res);
      }).catch(function (err) {
        console.log("addKey2 err -->", err);
        reject(err);
      });
    });
  };
  /**
   * 删除钥匙
   */

  removeKey = data => {
    uni.showLoading({
      title: '钥匙删除中'
    });
    return new Promise((resolve, reject) => {
      PLUGIN.removeKey({
        mode: data.mode,
        keyGroupId: data.keyUserId
      }).then(function (res) {
        uni.showToast({
          title: '钥匙已删除'
        });
        console.log("removeKey res -->", res);
        resolve(res);
      }).catch(function (err) {
        // wx.showToast({
        //   title: '删除失败',
        //   icon: "none"
        // })
        console.log("removeKey err -->", err);
        reject(err);
      });
    });
  };
  /**
   * 固件升级
   */

  OAD = url => {
    var self = this;
    uni.downloadFile({
      url: url,

      success(res) {
        console.log("download file success -->", res);

        if (res.statusCode === 200) {
          var fs = uni.getFileSystemManager();
          var data = fs.readFileSync(res.tempFilePath);
          PLUGIN.oad.on("oad:success", res => {
            console.log("oad:success res -->", res); // self.clearTimeout();

            uni.hideLoading();
          });
          PLUGIN.oad.on("oad:cancel", res => {
            console.log("oad:cancel res -->", res); // self.clearTimeout();

            uni.hideLoading();
          });
          PLUGIN.oad.on("oad:error", err => {
            console.log("oad:error err -->", err); // self.clearTimeout();

            uni.hideLoading();
            uni.showToast({
              title: '更新失败',
              icon: "none"
            });
          });
          PLUGIN.oad.on("oad:MTU", res => {
            console.log("oad:MTU res -->", res);

            if (res.data.MTU < 160) {
              self.ping();
            }
          }); // 监听升级进度

          PLUGIN.oad.on("oad:processing", res => {
            console.log(Date.now(), "oad:processing res -->", res);
          });
          PLUGIN.oad.digest(data);
          PLUGIN.oad.update();
        }
      }

    });
  };
  /**
   * 取消升级
   */

  cancelOAD = () => {
    PLUGIN.oad.cancel();
  };
  /**
   * 添加远程控制
   */

  addRemote = data => {
    uni.showLoading({
      title: '正在添加'
    });
    return new Promise((resolve, reject) => {
      if (PLUGIN.config.rfModuleType) {} else {
        PLUGIN.readDNAInfo().then(res => {
          // 每一个实例在调用 addRemoteControl 之前都需要确保设置rfModuleType
          PLUGIN.config.rfModuleType = res.data.DNAInfo.rfModuleType;
          PLUGIN.addRemoteControl(data).then(res => {
            uni.showToast({
              title: '添加成功'
            });
            console.log(res, '远程控制添加成功');
            resolve(res);
          }).catch(err => {
            uni.showToast({
              title: '操作失败',
              icon: "none"
            });
            console.log(err, '远程控制添加失败');
            reject(err);
          });
        }).catch(err => {
          uni.showToast({
            title: '操作失败',
            icon: "none"
          });
          reject(err);
        });
      }
    });
  };
  /**
   * 使能禁止
   * @param {*} options 
   */

  enableKey = options => {
    uni.showLoading({
      title: options.value ? '启用中' : '禁用中'
    });
    return new Promise((resolve, reject) => {
		
		// 蓝牙连接后需要延迟一定时间才能成功
		setTimeout(()=>{
			PLUGIN.enableKey(options).then(res => {
				console.log(options.value ? '已启用' : '已禁用');
				resolve(res);
			}).catch(err => {
				console.log(err)
				uni.showToast({
					title: '操作失败',
					icon: "none"
				});
				console.log(options.value ? '启用失败' : '禁用失败');
				reject(err);
			});
		}, 1000)
    });
  };
  /**
   * 发送心跳
   * 用以保持连接
   */

  ping = () => {
    console.log("ping -->");

    if (pingTimer) {
      clearTimeout(pingTimer);
      pingTimer = null;
    }

    var that = this;
    pingTimer = setTimeout(() => {
      that.checkPluginInstanaceIsConnnected() && that.currentPluginInstance.synchronizeLockRecord({
        limit: 0
      }); // 与设备交互可以延长断开连接时间，这里发送一个包来刷新断连的超时，limit设为0即不获取日志

      that.ping();
    }, TIMEOUT);
  };
  checkPluginInstanaceIsConnnected = () => {
    return this.currentPluginInstance && this.currentPluginInstance.connected;
  };
}

export { PluginManager };